package com.example.payment.service;

import com.example.payment.model.entity.Payment;
import com.example.payment.repository.PaymentRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * 支付服务实现类
 * 
 * @author mall-team
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PaymentService {

    private final PaymentRepository paymentRepository;

    /**
     * 模拟支付处理
     * 1. 创建支付记录
     * 2. 模拟支付成功（实际场景中会调用第三方支付接口）
     * 3. 更新支付状态
     * 
     * @param orderNo 订单编号
     * @param userId 用户ID
     * @param amount 支付金额
     * @return 支付流水号
     */
    @Transactional(rollbackFor = Exception.class)
    public String processPayment(String orderNo, Long userId, BigDecimal amount) {
        log.info("开始处理支付: orderNo={}, userId={}, amount={}", orderNo, userId, amount);

        // 1. 检查订单是否已支付
        if (paymentRepository.existsByOrderNo(orderNo)) {
            log.warn("订单已支付，跳过重复支付: orderNo={}", orderNo);
            Payment existingPayment = paymentRepository.findByOrderNo(orderNo)
                    .orElseThrow(() -> new RuntimeException("支付记录不存在"));
            return existingPayment.getPaymentNo();
        }

        // 2. 生成支付流水号
        String paymentNo = generatePaymentNo();

        // 3. 创建支付记录
        Payment payment = Payment.builder()
                .paymentNo(paymentNo)
                .orderNo(orderNo)
                .userId(userId)
                .amount(amount)
                .paymentMethod("MOCK")  // 模拟支付
                .status("PENDING")
                .remark("模拟支付处理")
                .build();

        paymentRepository.save(payment);
        log.info("支付记录创建成功: paymentNo={}", paymentNo);

        // 4. 模拟支付处理（实际场景中会调用第三方支付接口）
        try {
            // 模拟支付延迟
            Thread.sleep(1000);

            // 模拟支付成功
            payment.setStatus("SUCCESS");
            payment.setPaymentTime(LocalDateTime.now());
            payment.setThirdPartyTransactionNo("MOCK_" + UUID.randomUUID().toString().replace("-", ""));
            paymentRepository.save(payment);

            log.info("支付处理成功: paymentNo={}, orderNo={}", paymentNo, orderNo);
            return paymentNo;

        } catch (InterruptedException e) {
            log.error("支付处理被中断: paymentNo={}", paymentNo, e);
            Thread.currentThread().interrupt();
            
            // 更新支付状态为失败
            payment.setStatus("FAILED");
            payment.setRemark("支付处理失败: " + e.getMessage());
            paymentRepository.save(payment);
            
            throw new RuntimeException("支付处理失败", e);
        }
    }

    /**
     * 根据订单编号查询支付记录
     * 
     * @param orderNo 订单编号
     * @return 支付记录
     */
    @Transactional(readOnly = true)
    public Payment getPaymentByOrderNo(String orderNo) {
        return paymentRepository.findByOrderNo(orderNo)
                .orElseThrow(() -> new RuntimeException("支付记录不存在: " + orderNo));
    }

    /**
     * 生成支付流水号
     * 格式: PAY + 时间戳 + UUID前8位
     */
    private String generatePaymentNo() {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        return "PAY" + timestamp + uuid;
    }
}

